package cn.jdemo.type;

import java.lang.reflect.*;
import java.util.List;
import java.util.Map;

/**
 * @see java.lang.reflect.WildcardType 通配符类型:针对方法参数的泛型类型
 * @see WildcardType#getLowerBounds()
 * @see WildcardType#getUpperBounds()
 *
 * @date 2020/12/29
 */
public class Demo04_WildcardType {
    public static void main(String[] args) {
        //test01(); 错误
        test02();// 正确:(1)先获取参数泛型类型(2)然后在获取上下边界
    }

    /**
     * 输出内容:
     *  空
     */
    public static void test01() {
        try {
            Method method01 = B.class.getMethod("method01", Map.class);
            Type[] genericParameterTypes = method01.getGenericParameterTypes();
            for (Type genericParameterType:genericParameterTypes){

                handlerType(genericParameterType);

            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    /**
     * *************WildcardType***************
     * UpperBounds(): java.lang.Number
     * *************WildcardType***************
     * LowerBounds(): java.lang.Object
     * UpperBounds(): java.lang.Object
     *
     */
    public static void test02() {
        try {
            Method method01 = B.class.getMethod("method01", Map.class);
            Type[] genericParameterTypes = method01.getGenericParameterTypes();
            for (Type genericParameterType:genericParameterTypes){
                // 先转为ParameterizedType
                if (genericParameterType instanceof ParameterizedType){
                    ParameterizedType parameterizedType = (ParameterizedType) genericParameterType;
                    Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();

                    for (Type actualTypeArgument:actualTypeArguments){
                        handlerType(actualTypeArgument);
                    }
                }
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }

    public static void handlerType(Type tempType){
        // WildcardType，获取的是参数泛型的上下边界信息
        if (tempType instanceof WildcardType){
            System.out.println("*************WildcardType***************");
            WildcardType wildcardType = (WildcardType) tempType;
            Type[] lowerBounds = wildcardType.getLowerBounds();
            for (Type type:lowerBounds){
                System.out.println("LowerBounds(): "+type.getTypeName());
            }
            Type[] upperBounds = wildcardType.getUpperBounds();
            for (Type type:upperBounds){
                System.out.println("UpperBounds(): "+type.getTypeName());
            }
        }
        // TypeVariable ： 输出空的原因,获取的是定义在(Class、Constructor，Method)上的泛型类型变量
        if (tempType instanceof TypeVariable){
            System.out.println("*************TypeVariable***************");
            TypeVariable typeVariable = (TypeVariable) tempType;
            Type[] bounds = typeVariable.getBounds();
            for (Type type:bounds){
                System.out.println("Bounds(): "+type.getTypeName());
            }
        }
    }
}

class B{
    public void method01(Map<? extends Number, ? super Object> map){
    }
    public void method02(List<? extends Number> map){
    }
}